package com.ruoyi.shop.common.utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
/**
 * ClassName: RedisIdWorker
 * Package: com.hmdp.utils
 * Description: 分布式全局的唯一id的其中的一种策略, 其实是有很多策略的，学习思路
 */
@Component
public class RedisIdWorker {

    /**
     * 开始时间戳
     * 一般32位的可以使用69年左右，可以拿计算机算算
     */
    private static final Long twepoch = 1704067200L;

    /**
     * 序列号
     */
    private static final Long COUNT_BITS = 32L;

    /**
     * 非Component组件类注入
     * @param args
     */
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    public static void main(String[] args) {
        LocalDateTime now = LocalDateTime.of(2024, 1, 1, 0, 0, 0);
        long epochSecond = now.toEpochSecond(ZoneOffset.UTC);
        System.out.println("开始时间戳为: " + epochSecond);
    }
    /**
     * 生成全局唯一id
     */
    public Long nextId(String keyPre){
        /**
         * 1 生成时间戳
         */
        LocalDateTime now = LocalDateTime.now();
        long timestamp = now.toEpochSecond(ZoneOffset.UTC);
        timestamp -= twepoch;

        /**
         * 2 获取当前的日期
         * 3 获取count
         */
        String date = now.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        // increment可以返回累加后的redis对应的value
        Long count = stringRedisTemplate.opsForValue().increment(keyPre + ":" + date);
        // 如果对应的key没有, 则创建
        if (count == null) {
            stringRedisTemplate.opsForValue().setIfAbsent(keyPre + timestamp, "0");
            count = 1L;
        }

        // 返回加密的id
        return ((timestamp << COUNT_BITS) | count);
    }
}